
package com.gcloud.controller.compute.service.vm.zone.impl;

import com.gcloud.common.util.StringUtils;
import com.gcloud.controller.compute.dao.ComputeNodeDao;
import com.gcloud.controller.compute.dao.ZoneDao;
import com.gcloud.controller.compute.entity.AvailableZoneEntity;
import com.gcloud.controller.compute.entity.ComputeNode;
import com.gcloud.controller.compute.service.vm.zone.IVmZoneService;
import com.gcloud.controller.compute.utils.RedisNodesUtil;
import com.gcloud.core.exception.GCloudException;
import com.gcloud.framework.db.PageResult;
import com.gcloud.header.compute.msg.api.model.AvailableZone;

import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
@Slf4j
public class VmZoneServiceImpl implements IVmZoneService {

    @Autowired
    private ZoneDao zoneDao;

    @Autowired
    private ComputeNodeDao nodeDao;

    @Override
    public PageResult<AvailableZone> describeZones(Integer pageNumber, Integer pageSize) {
        PageResult page = this.zoneDao.findBySql("SELECT * FROM gc_zones", pageNumber, pageSize);
        List<AvailableZone> vos = new ArrayList<>();
        for (Object obj : page.getList()) {
            AvailableZoneEntity entity = (AvailableZoneEntity)obj;
            AvailableZone vo = new AvailableZone();
            vo.setZoneId(entity.getId());
            vo.setLocalName(entity.getName());
            vos.add(vo);
        }
        page.setList(vos);
        return page;
    }

    @Override
    public void createZone(String zoneName) {
        synchronized (VmZoneServiceImpl.class) {
            if (this.zoneDao.findUniqueByProperty("name", zoneName) != null) {
                throw new GCloudException("zone name exists");
            }
            AvailableZoneEntity zone = new AvailableZoneEntity();
            zone.setId(StringUtils.genUuid());
            zone.setName(zoneName);
            this.zoneDao.save(zone);
        }
    }

    @Override
    public void updateComputeNodeZone(String zoneId, List<Integer> nodeIds) {
        AvailableZoneEntity zone = this.zoneDao.getById(zoneId);
        if (zone == null) {
            throw new GCloudException("zone not found");
        }
        if (nodeIds != null) {
            for (Integer nodeId : nodeIds) {
                ComputeNode node = this.nodeDao.getById(nodeId);
                if (node != null) {
                    node.setZoneId(zoneId);
                    List<String> updateField = new ArrayList<>();
                    updateField.add("zoneId");
                    this.nodeDao.update(node, updateField);
                    RedisNodesUtil.updateComputeNodeZone(node.getHostname(), zoneId);
                }
            }
        }
    }

}
